﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Reflection;
using System.Runtime.Remoting.Contexts;
using System.Security.Cryptography.X509Certificates;
using System.Text;

using System.Data;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
using System.Web;
using Microsoft.VisualBasic.FileIO;

namespace CommonLibrary
{
    public class NetClass
    {
        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="in_frfile"></param>
        /// <param name="in_tofile"></param>
        /// <returns></returns>
        public static bool DownFile(string in_frfile, string in_tofile)
        {
            try
            {
                try
                {
                    WebRequest myre = WebRequest.Create(in_frfile);
                }
                catch (WebException err)
                {
                    FileClass.Log(err);
                    return false;
                }

                WebClientTimeout client = new WebClientTimeout();
                while (true)
                {
                    try
                    {
                        if (File.Exists(in_tofile))
                        {
                            File.Delete(in_tofile);
                        }

                        FileInfo fileInfo = new FileInfo(in_tofile);
                        if (Directory.Exists(fileInfo.Directory.FullName) == false)
                        {
                            Directory.CreateDirectory(fileInfo.Directory.FullName);
                        }

                        client.DownloadFile(in_frfile, in_tofile);
                        break;
                    }
                    catch (WebException err)
                    {
                        if (err.Message.Contains("(504)"))//504网关超时
                        {
                            continue;
                        }

                        FileClass.Log(err);
                        return false;
                    }
                }

                return true;
            }
            catch (WebException err)
            {
                FileClass.Log(err);
                return false;
            }

        }

        public static bool DownFile(string in_frfile, string in_tofile, CookieContainer cookieContainer)
        {
            HttpWebResponse jpghttpWebResponse = NetClass.CreateGetHttpResponse(in_frfile, null, null, cookieContainer);

            if (File.Exists(in_tofile))
            {
                File.Delete(in_tofile);
            }

            FileInfo fileInfo = new FileInfo(in_tofile);
            if (Directory.Exists(fileInfo.Directory.FullName) == false)
            {
                Directory.CreateDirectory(fileInfo.Directory.FullName);
            }

            using (Stream stream = jpghttpWebResponse.GetResponseStream())
            {
                stream.ClSaveStreamToFile(in_tofile);
            }
            return true;
        }



        /// <summary>
        /// 得到网站根路径
        /// </summary>
        /// <returns></returns>
        public static string GetWebRoot()
        {
            //获取Web地址
            string url = HttpContext.Current.Request.Url.ToString();
            string[] arr1 = System.Text.RegularExpressions.Regex.Split(url, "://", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            if (arr1.Length == 0) return "";

            string[] arr2 = System.Text.RegularExpressions.Regex.Split(arr1[1], "/", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            if (arr2.Length == 0) return "";

            string webRoot = arr1[0] + "://" + arr2[0];
            return webRoot;
        }

        /// <summary>
        /// 获取客户端IP
        /// </summary>
        /// <returns></returns>
        public static string GetClientIP()
        {
            string result = String.Empty;
            result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (result != null && result != String.Empty)
            {
                //可能有代理 
                if (result.IndexOf(".") == -1)    //没有"."肯定是非IPv4格式 
                    result = null;
                else
                {
                    if (result.IndexOf(",") != -1)
                    {
                        //有","，估计多个代理。取第一个不是内网的IP。 
                        result = result.Replace(" ", "");
                        string[] temparyip = result.Split(",;".ToCharArray());
                        for (int i = 0; i < temparyip.Length; i++)
                        {
                            if (IsIPAddress(temparyip[i])
                                && temparyip[i].Substring(0, 3) != "10."
                                && temparyip[i].Substring(0, 7) != "192.168"
                                && temparyip[i].Substring(0, 7) != "172.16.")
                            {
                                return temparyip[i];    //找到不是内网的地址 
                            }
                        }
                    }
                    else if (IsIPAddress(result)) //代理即是IP格式 
                        return result;
                    else
                        result = null;    //代理中的内容 非IP，取IP 
                }
            }
            string IpAddress = (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null && HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != String.Empty) ? HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] : HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            if (null == result || result == String.Empty)
                result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            if (result == null || result == String.Empty)
                result = HttpContext.Current.Request.UserHostAddress;
            return result;
        }


        //// <summary>
        /// 判断是否是IP地址格式 0.0.0.0
        /// </summary>
        /// <param name="str1">待判断的IP地址</param>
        /// <returns>true or false</returns>
        public static bool IsIPAddress(string str1)
        {
            if (str1 == null || str1 == string.Empty || str1.Length < 7 || str1.Length > 15) return false;
            string regformat = @"^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$";
            Regex regex = new Regex(regformat, RegexOptions.IgnoreCase);
            return regex.IsMatch(str1);
        }


        /// <summary>
        /// 根据服务器路径得到本地路径
        /// </summary>
        /// <param name="in_path"></param>
        /// <returns></returns>
        public static string GetServerMapPath(string in_path)
        {
            return HttpContext.Current.Server.MapPath(in_path);
        }


        public static string GetWebText(string in_url, Encoding encoding)
        {
            HttpWebRequest loHttp = (HttpWebRequest)WebRequest.Create(in_url);
            loHttp.Timeout = 1000000;     // 1000 secs
            loHttp.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)";

            HttpWebResponse loWebResponse;
            loWebResponse = (HttpWebResponse)loHttp.GetResponse();

            StreamReader loResponseStream = new StreamReader(loWebResponse.GetResponseStream(), encoding);
            string lcHtml = loResponseStream.ReadToEnd();
            loWebResponse.Close();
            loResponseStream.Close();

            return lcHtml;
        }


        private static readonly string DefaultUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";

        /// <summary>  
        /// 创建GET方式的HTTP请求  
        /// </summary>  
        /// <param name="url">请求的URL</param>  
        /// <param name="timeout">请求的超时时间</param>  
        /// <param name="userAgent">请求的客户端浏览器信息，可以为空</param>  
        /// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>  
        /// <returns></returns>  
        public static HttpWebResponse CreateGetHttpResponse(string url, int? timeout, string userAgent, CookieContainer cookieContainer)
        {
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException("url");
            }
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = "GET";
            request.UserAgent = DefaultUserAgent;
            if (!string.IsNullOrEmpty(userAgent))
            {
                request.UserAgent = userAgent;
            }
            if (timeout.HasValue)
            {
                request.Timeout = timeout.Value;
            }
            if (cookieContainer != null)
            {
                request.CookieContainer = cookieContainer;
            }
            return request.GetResponse() as HttpWebResponse;
        }

        /// <summary>  
        /// 创建POST方式的HTTP请求  
        /// </summary>  
        /// <param name="url">请求的URL</param>  
        /// <param name="parameters">随同请求POST的参数名称及参数值字典</param>  
        /// <param name="timeout">请求的超时时间</param>  
        /// <param name="userAgent">请求的客户端浏览器信息，可以为空</param>  
        /// <param name="requestEncoding">发送HTTP请求时所用的编码</param>  
        /// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>  
        /// <returns></returns>  
        public static HttpWebResponse CreatePostHttpResponse(string url, IDictionary<string, string> parameters, int? timeout, string userAgent, Encoding requestEncoding, CookieContainer cookieContainer)
        {
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException("url");
            }
            if (requestEncoding == null)
            {
                throw new ArgumentNullException("requestEncoding");
            }
            HttpWebRequest request = null;
            //如果是发送HTTPS请求  
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                request = WebRequest.Create(url) as HttpWebRequest;
                request.ProtocolVersion = HttpVersion.Version10;
            }
            else
            {
                request = WebRequest.Create(url) as HttpWebRequest;
            }
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            if (!string.IsNullOrEmpty(userAgent))
            {
                request.UserAgent = userAgent;
            }
            else
            {
                request.UserAgent = DefaultUserAgent;
            }

            if (timeout.HasValue)
            {
                request.Timeout = timeout.Value;
            }
            if (cookieContainer != null)
            {
                request.CookieContainer = cookieContainer;
            }
            //如果需要POST数据  
            if (!(parameters == null || parameters.Count == 0))
            {
                StringBuilder buffer = new StringBuilder();
                int i = 0;
                foreach (string key in parameters.Keys)
                {
                    if (i > 0)
                    {
                        buffer.AppendFormat("&{0}={1}", key, parameters[key]);
                    }
                    else
                    {
                        buffer.AppendFormat("{0}={1}", key, parameters[key]);
                    }
                    i++;
                }
                byte[] data = requestEncoding.GetBytes(buffer.ToString());
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
            }

            return request.GetResponse() as HttpWebResponse;
        }

        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true; //总是接受  
        }

        /// <summary>  
        /// 创建POST方式的HTTP请求  
        /// </summary>  
        /// <param name="url">请求的URL</param>  
        /// <param name="postStr">随同请求POST的字符串</param>  
        /// <param name="timeout">请求的超时时间</param>  
        /// <param name="userAgent">请求的客户端浏览器信息，可以为空</param>  
        /// <param name="requestEncoding">发送HTTP请求时所用的编码</param>  
        /// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>  
        /// <returns></returns>  
        public static HttpWebResponse CreatePostHttpResponse(string url, string postStr, int? timeout, string userAgent, Encoding requestEncoding, CookieContainer cookieContainer)
        {
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException("url");
            }
            if (requestEncoding == null)
            {
                throw new ArgumentNullException("requestEncoding");
            }
            HttpWebRequest request = null;
            //如果是发送HTTPS请求  
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                request = WebRequest.Create(url) as HttpWebRequest;
                request.ProtocolVersion = HttpVersion.Version10;
            }
            else
            {
                request = WebRequest.Create(url) as HttpWebRequest;
            }
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            if (!string.IsNullOrEmpty(userAgent))
            {
                request.UserAgent = userAgent;
            }
            else
            {
                request.UserAgent = DefaultUserAgent;
            }

            if (timeout.HasValue)
            {
                request.Timeout = timeout.Value;
            }
            if (cookieContainer != null)
            {
                request.CookieContainer = cookieContainer;
            }
            //如果需要POST数据  
            if (string.IsNullOrWhiteSpace(postStr) == false)
            {
                byte[] data = requestEncoding.GetBytes(postStr);
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
            }

            return request.GetResponse() as HttpWebResponse;
        }



        /// <summary>  
        /// 创建GET方式的HTTP请求并返回字符串
        /// </summary>  
        /// <param name="url">请求的URL</param>  
        /// <param name="timeout">请求的超时时间</param>  
        /// <param name="userAgent">请求的客户端浏览器信息，可以为空</param>  
        /// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>  
        /// <returns></returns>  
        public static string HttpGetReturn(string url, int? timeout, string userAgent, Encoding requestEncoding, CookieContainer cookieContainer)
        {
            string str = "";
            HttpWebResponse httpWebResponse = CreateGetHttpResponse(url, timeout, userAgent, cookieContainer);
            using (StreamReader loResponseStream = new StreamReader(httpWebResponse.GetResponseStream(), (requestEncoding ?? Encoding.UTF8)))
            {
                str = loResponseStream.ReadToEnd();
            }
            httpWebResponse.Close();
            return str;
        }

        /// <summary>  
        /// 创建POST方式的HTTP请求并返回字符串
        /// </summary>  
        /// <param name="url">请求的URL</param>  
        /// <param name="parameters">随同请求POST的参数名称及参数值字典</param>  
        /// <param name="timeout">请求的超时时间</param>  
        /// <param name="userAgent">请求的客户端浏览器信息，可以为空</param>  
        /// <param name="requestEncoding">发送HTTP请求时所用的编码</param>  
        /// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>  
        /// <returns></returns>  
        public static string HttpPostReturn(string url, IDictionary<string, string> parameters, int? timeout, string userAgent, Encoding requestEncoding, CookieContainer cookieContainer)
        {
            string str = "";
            HttpWebResponse httpWebResponse = CreatePostHttpResponse(url, parameters, timeout, userAgent, (requestEncoding ?? Encoding.UTF8), cookieContainer);
            using (StreamReader loResponseStream = new StreamReader(httpWebResponse.GetResponseStream(), (requestEncoding ?? Encoding.UTF8)))
            {
                str = loResponseStream.ReadToEnd();
            }
            httpWebResponse.Close();
            return str;
        }

        /// <summary>  
        /// 创建POST方式的HTTP请求并返回字符串
        /// </summary>  
        /// <param name="url">请求的URL</param>  
        /// <param name="postStr">随同请求POST的字符串</param>  
        /// <param name="timeout">请求的超时时间</param>  
        /// <param name="userAgent">请求的客户端浏览器信息，可以为空</param>  
        /// <param name="requestEncoding">发送HTTP请求时所用的编码</param>  
        /// <param name="cookies">随同HTTP请求发送的Cookie信息，如果不需要身份验证可以为空</param>  
        /// <returns></returns>  

        public static string HttpPostReturn(string url, string postStr, int? timeout, string userAgent, Encoding requestEncoding, CookieContainer cookieContainer)
        {
            string str = "";
            HttpWebResponse httpWebResponse = CreatePostHttpResponse(url, postStr, timeout, userAgent, (requestEncoding ?? Encoding.UTF8), cookieContainer);
            using (StreamReader loResponseStream = new StreamReader(httpWebResponse.GetResponseStream(), (requestEncoding ?? Encoding.UTF8)))
            {
                str = loResponseStream.ReadToEnd();
            }
            httpWebResponse.Close();
            return str;
        }

        /// <summary>
        /// 上传的方法
        /// </summary>
        /// <param name="uploadfile">单个文件名（上传多个文件的方法自己修改）</param>
        /// <param name="url">post请求的url</param>
        /// <param name="poststring">post的字符串 键值对，相当于表单上的文本框里的字符</param>
        /// <returns></returns>
        public static string HttpPostFileReturn(string url, Dictionary<string, string> dictionary, string uploadfile, int? timeout, string userAgent, Encoding requestEncoding, CookieContainer cookieContainer)
        {
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException("url");
            }
    

            HttpWebRequest request = null;
            //如果是发送HTTPS请求  
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                request = WebRequest.Create(url) as HttpWebRequest;
                request.ProtocolVersion = HttpVersion.Version10;
            }
            else
            {
                request = WebRequest.Create(url) as HttpWebRequest;
            }
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            if (!string.IsNullOrEmpty(userAgent))
            {
                request.UserAgent = userAgent;
            }
            else
            {
                request.UserAgent = DefaultUserAgent;
            }

            if (timeout.HasValue)
            {
                request.Timeout = timeout.Value;
            }
            if (cookieContainer != null)
            {
                request.CookieContainer = cookieContainer;
            }


            string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
            request.ContentType = "multipart/form-data; boundary=" + boundary;
            request.Method = "POST";
            

            #region Build up the post message header 

            StringBuilder sb = new StringBuilder();

            //加文本
            if (dictionary != null)
            {
                foreach (string key in dictionary.Keys)
                {
                    sb.Append("--");
                    sb.Append(boundary);
                    sb.Append("\r\n");
                    sb.Append("Content-Disposition: form-data; name=\"");
                    sb.Append(key);
                    sb.Append("\"");
                    sb.Append("\r\n");
                    sb.Append("\r\n");
                    sb.Append(dictionary[key]);
                    sb.Append("\r\n");
                }
            }

            //加文件
            sb.Append("--");
            sb.Append(boundary);
            sb.Append("\r\n");
            sb.Append("Content-Disposition: form-data; name=\"filename\";");
            sb.Append("filename=\"");
            sb.Append(Path.GetFileName(uploadfile));
            sb.Append("\"");
            sb.Append("\r\n");
            sb.Append("Content-Type: multipart/form-data");
            sb.Append("\r\n");
            sb.Append("\r\n");

            string postHeader = sb.ToString();
            byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader); 

            #endregion

            // Build the trailing boundary string as a byte array 
            // ensuring the boundary appears on a line by itself 
            byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");

            FileStream fileStream = new FileStream(uploadfile, FileMode.Open, FileAccess.Read);
            long length = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length;
            request.ContentLength = length;

            Stream requestStream = request.GetRequestStream();

            // Write out our post header 
            requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);

            // Write out the file contents 
            byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))];
            int bytesRead = 0;
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                requestStream.Write(buffer, 0, bytesRead);
            }
            fileStream.Close();

            // Write out the trailing boundary 
            requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);

            HttpWebResponse httpWebResponse = request.GetResponse() as HttpWebResponse;

            string str = "";
            using (StreamReader loResponseStream = new StreamReader(httpWebResponse.GetResponseStream(), (requestEncoding ?? Encoding.UTF8)))
            {
                str = loResponseStream.ReadToEnd();
            }
        
            requestStream.Close();
            httpWebResponse.Close();
            return str;
        }


    }


}
